package svg.hw.quiz;


import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;

import javax.swing.*;

import svg.hw.recog.ImageData;

public class DigitizerPanel extends JPanel {

    /**
     * The down sampled pixel map of what the user has drawn
     */
    protected ImageData pixelMap;

    /**
     * The downsample width for the application.
     */
    protected int downSampleWidth;

    /**
     * The down sample height for the application.
     */
    protected int downSampleHeight;


    public DigitizerPanel() {
        setBackground(Color.white);
        addMouseListener(new MouseHandler());
    }

    public ImageData getSample() {
        return pixelMap;
    }

    public void setSample(ImageData sample) {
        pixelMap = sample;
        repaint();
    }

    public void setSampleWidth(int width) {
        downSampleWidth = width;
    }

    public void setSampleHeight(int height) {
        downSampleHeight = height;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D)g;
        drawGrid(g2d);

        if (pixelMap == null)
            return;

        int w = this.getWidth();
        int h = this.getHeight();

        float wr = (float) w /(float)pixelMap.getWidth();
        float hr = (float) h /(float)pixelMap.getHeight();

        float l = 0;
        float t = 0;
        for (int y = 0; y < pixelMap.getHeight(); y++) {
            for (int x = 0; x < pixelMap.getWidth(); x++) {
                Rectangle2D r2 =
                    new Rectangle2D.Float(l, t, wr, hr);
                if (pixelMap.getData(x, y) != 0) {
                    g2d.fill(r2);
                }
                l = l + wr;
            }
            t = t + hr;
            l = 0;
        }
    }

    /**
     * Draws a grid
     * @param g Graphics2D grphics 2d object
     */
    private void drawGrid(Graphics2D g) {
        int w = this.getWidth();
        int h = this.getHeight();

        g.drawRect(0,0, w-1, h-1);

        // draw the vertical lines
        float wr = (float) w / (float)downSampleWidth;
        for (int x = 0; x < downSampleWidth; x++) {
            float x1 = x * wr;
            Line2D line = new Line2D.Float(x1, 0, x1, h);
            g.draw(line);
        }

        // draw the horizontal lines
        float hr = (float) h /(float)downSampleHeight;
        for (int y = 0; y < downSampleHeight; y++) {
            float y1 = y * hr;
            Line2D line = new Line2D.Float(0, y1, w, y1);
            g.draw(line);
        }
    }

    private void setPixel(int mouseX, int mouseY) {
        int pixelX = (mouseX * downSampleWidth)  / this.getWidth();
        int pixelY = (mouseY * downSampleHeight) / this.getHeight();

        if (pixelMap == null) {
            return;
        }

        int pixelValue = pixelMap.getData(pixelX, pixelY);
        pixelValue = ~pixelValue & 1; // acts as boolean inverse
        pixelMap.setData(pixelX, pixelY, pixelValue);

        repaint();
    }

    class MouseHandler extends MouseAdapter {
        public void mouseClicked(MouseEvent e) {
            setPixel(e.getX(), e.getY());
        }
    }
}
